package hawk.example.bookstore.update;

import static glz.hawkframework.support.ArgumentSupport.*;

import glz.hawkframework.dao.base.function.ColumnDescriptor;
import glz.hawkframework.dao.base.function.ColumnFunction;
import glz.hawkframework.dao.base.function.IRecord;
import glz.hawkframework.dao.base.function.RecordCreateDateTimeFunction;
import glz.hawkframework.dao.base.function.RecordCreateUserIdFunction;
import glz.hawkframework.dao.base.function.RecordIdFunction;
import glz.hawkframework.dao.base.function.RecordUpdateDateTimeFunction;
import glz.hawkframework.dao.base.function.RecordUpdateUserIdFunction;
import glz.hawkframework.dao.base.function.RecordVersionFunction;

import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * Map to table: BOOK_AUTHOR_MAP
 */
public class BookAuthorMapUpdate implements IRecord {
    /**
     * Map to column: BOOK_AUTHOR_MAP_ID
     */
    private BigInteger bookAuthorMapId;
    /**
     * Map to column: BOOK_AUTHOR_MAP_ID
     */
    private boolean bookAuthorMapIdUpdated = false;
    /**
     * Map to column: AUTHOR_ID
     */
    private BigInteger authorId;
    /**
     * Map to column: AUTHOR_ID
     */
    private boolean authorIdUpdated = false;
    /**
     * Map to column: BOOK_ID
     */
    private BigInteger bookId;
    /**
     * Map to column: BOOK_ID
     */
    private boolean bookIdUpdated = false;
    /**
     * Map to column: CREATE_DATE_TIME
     */
    private LocalDateTime createDateTime;
    /**
     * Map to column: CREATE_DATE_TIME
     */
    private boolean createDateTimeUpdated = false;
    /**
     * Map to column: UPDATE_DATE_TIME
     */
    private LocalDateTime updateDateTime;
    /**
     * Map to column: UPDATE_DATE_TIME
     */
    private boolean updateDateTimeUpdated = false;
    /**
     * Map to column: DELETE_DATE_TIME
     */
    private LocalDateTime deleteDateTime;
    /**
     * Map to column: DELETE_DATE_TIME
     */
    private boolean deleteDateTimeUpdated = false;
    /**
     * Map to column: CREATE_USER_ID
     */
    private String createUserId;
    /**
     * Map to column: CREATE_USER_ID
     */
    private boolean createUserIdUpdated = false;
    /**
     * Map to column: UPDATE_USER_ID
     */
    private String updateUserId;
    /**
     * Map to column: UPDATE_USER_ID
     */
    private boolean updateUserIdUpdated = false;
    /**
     * Map to column: DELETE_USER_ID
     */
    private String deleteUserId;
    /**
     * Map to column: DELETE_USER_ID
     */
    private boolean deleteUserIdUpdated = false;
    /**
     * Map to column: RECORD_VERSION
     */
    private Long recordVersion;
    /**
     * Map to column: RECORD_VERSION
     */
    private boolean recordVersionUpdated = false;
    /**
     * This map holds the relations between function class and column
     */
    private final Map<Class<? extends ColumnFunction>, ColumnDescriptor<?>> functionMap = new HashMap<>();

    {
        functionMap.put(RecordIdFunction.class, new ColumnDescriptor<>("BOOK_AUTHOR_MAP_ID", "bookAuthorMapId", this::getBookAuthorMapId, this::isBookAuthorMapIdUpdated, this::setBookAuthorMapId));
        functionMap.put(RecordCreateDateTimeFunction.class, new ColumnDescriptor<>("CREATE_DATE_TIME", "createDateTime", this::getCreateDateTime, this::isCreateDateTimeUpdated, this::setCreateDateTime));
        functionMap.put(RecordUpdateDateTimeFunction.class, new ColumnDescriptor<>("UPDATE_DATE_TIME", "updateDateTime", this::getUpdateDateTime, this::isUpdateDateTimeUpdated, this::setUpdateDateTime));
        functionMap.put(RecordCreateUserIdFunction.class, new ColumnDescriptor<>("CREATE_USER_ID", "createUserId", this::getCreateUserId, this::isCreateUserIdUpdated, this::setCreateUserId));
        functionMap.put(RecordUpdateUserIdFunction.class, new ColumnDescriptor<>("UPDATE_USER_ID", "updateUserId", this::getUpdateUserId, this::isUpdateUserIdUpdated, this::setUpdateUserId));
        functionMap.put(RecordVersionFunction.class, new ColumnDescriptor<>("RECORD_VERSION", "recordVersion", this::getRecordVersion, this::isRecordVersionUpdated, this::setRecordVersion));
    }

    /**
     * Map to column: BOOK_AUTHOR_MAP_ID
     */
    public BigInteger getBookAuthorMapId() {
        return bookAuthorMapId;
    }

    /**
     * Map to column: BOOK_AUTHOR_MAP_ID
     */
    public boolean isBookAuthorMapIdUpdated() {
        return bookAuthorMapIdUpdated;
    }

    /**
     * Map to column: BOOK_AUTHOR_MAP_ID
     */
    public void setBookAuthorMapId(BigInteger bookAuthorMapId) {
        this.bookAuthorMapId = bookAuthorMapId;
        this.bookAuthorMapIdUpdated = true;
    }

    /**
     * Map to column: AUTHOR_ID
     */
    public BigInteger getAuthorId() {
        return authorId;
    }

    /**
     * Map to column: AUTHOR_ID
     */
    public boolean isAuthorIdUpdated() {
        return authorIdUpdated;
    }

    /**
     * Map to column: AUTHOR_ID
     */
    public void setAuthorId(BigInteger authorId) {
        this.authorId = authorId;
        this.authorIdUpdated = true;
    }

    /**
     * Map to column: BOOK_ID
     */
    public BigInteger getBookId() {
        return bookId;
    }

    /**
     * Map to column: BOOK_ID
     */
    public boolean isBookIdUpdated() {
        return bookIdUpdated;
    }

    /**
     * Map to column: BOOK_ID
     */
    public void setBookId(BigInteger bookId) {
        this.bookId = bookId;
        this.bookIdUpdated = true;
    }

    /**
     * Map to column: CREATE_DATE_TIME
     */
    public LocalDateTime getCreateDateTime() {
        return createDateTime;
    }

    /**
     * Map to column: CREATE_DATE_TIME
     */
    public boolean isCreateDateTimeUpdated() {
        return createDateTimeUpdated;
    }

    /**
     * Map to column: CREATE_DATE_TIME
     */
    public void setCreateDateTime(LocalDateTime createDateTime) {
        this.createDateTime = createDateTime;
        this.createDateTimeUpdated = true;
    }

    /**
     * Map to column: UPDATE_DATE_TIME
     */
    public LocalDateTime getUpdateDateTime() {
        return updateDateTime;
    }

    /**
     * Map to column: UPDATE_DATE_TIME
     */
    public boolean isUpdateDateTimeUpdated() {
        return updateDateTimeUpdated;
    }

    /**
     * Map to column: UPDATE_DATE_TIME
     */
    public void setUpdateDateTime(LocalDateTime updateDateTime) {
        this.updateDateTime = updateDateTime;
        this.updateDateTimeUpdated = true;
    }

    /**
     * Map to column: DELETE_DATE_TIME
     */
    public LocalDateTime getDeleteDateTime() {
        return deleteDateTime;
    }

    /**
     * Map to column: DELETE_DATE_TIME
     */
    public boolean isDeleteDateTimeUpdated() {
        return deleteDateTimeUpdated;
    }

    /**
     * Map to column: DELETE_DATE_TIME
     */
    public void setDeleteDateTime(LocalDateTime deleteDateTime) {
        this.deleteDateTime = deleteDateTime;
        this.deleteDateTimeUpdated = true;
    }

    /**
     * Map to column: CREATE_USER_ID
     */
    public String getCreateUserId() {
        return createUserId;
    }

    /**
     * Map to column: CREATE_USER_ID
     */
    public boolean isCreateUserIdUpdated() {
        return createUserIdUpdated;
    }

    /**
     * Map to column: CREATE_USER_ID
     */
    public void setCreateUserId(String createUserId) {
        this.createUserId = createUserId;
        this.createUserIdUpdated = true;
    }

    /**
     * Map to column: UPDATE_USER_ID
     */
    public String getUpdateUserId() {
        return updateUserId;
    }

    /**
     * Map to column: UPDATE_USER_ID
     */
    public boolean isUpdateUserIdUpdated() {
        return updateUserIdUpdated;
    }

    /**
     * Map to column: UPDATE_USER_ID
     */
    public void setUpdateUserId(String updateUserId) {
        this.updateUserId = updateUserId;
        this.updateUserIdUpdated = true;
    }

    /**
     * Map to column: DELETE_USER_ID
     */
    public String getDeleteUserId() {
        return deleteUserId;
    }

    /**
     * Map to column: DELETE_USER_ID
     */
    public boolean isDeleteUserIdUpdated() {
        return deleteUserIdUpdated;
    }

    /**
     * Map to column: DELETE_USER_ID
     */
    public void setDeleteUserId(String deleteUserId) {
        this.deleteUserId = deleteUserId;
        this.deleteUserIdUpdated = true;
    }

    /**
     * Map to column: RECORD_VERSION
     */
    public Long getRecordVersion() {
        return recordVersion;
    }

    /**
     * Map to column: RECORD_VERSION
     */
    public boolean isRecordVersionUpdated() {
        return recordVersionUpdated;
    }

    /**
     * Map to column: RECORD_VERSION
     */
    public void setRecordVersion(Long recordVersion) {
        this.recordVersion = recordVersion;
        this.recordVersionUpdated = true;
    }

    @Override
    public Optional<ColumnDescriptor<?>> findColumnDescriptor(Class<? extends ColumnFunction> columnFunctionClass) {
        return Optional.ofNullable(functionMap.get(argNotNull(columnFunctionClass, "columnFunctionClass")));
    }
}
